package com.newgrand.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.newgrand.domain.model.*;
import com.newgrand.service.SettleService;
import com.newgrand.utils.*;
import com.newgrand.utils.i8util.I8Converter;
import com.newgrand.utils.i8util.I8Request;
import lombok.RequiredArgsConstructor;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service

@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class SettleImpl extends GetPhIdHelper  implements SettleService {

    private static final OpenApiClient client = new OpenApiClient(YamlConstants.getPropertiesKey("yl.baseUrl"), YamlConstants.getPropertiesKey("yl.accessId"), YamlConstants.getPropertiesKey("yl.secretKey"));
    private static final String pcrApi = "/mquantity/m-settle-order-params?orgId=%d&version=%d&limit=%d&offset=%d";
    private static final Logger logger = LogManager.getLogger(SettleImpl.class);
    private static final NGLog ngLog = new NGLog();
    private final I8Request i8Request;
    private static final String mstformData = "{\"form\":{\"key\":\"PhId\",\"newRow\":{\"BillNo\":\"\",\"Title\":\"\",\"BillDt\":\"\",\"PhidCnt\":\"\",\"CntTitle\":\"\",\"Cycle\":\"\",\"DtStart\":\"\",\"PhidPc\":\"\",\"PhidOCode\":\"\",\"DtEnd\":\"\",\"RecCompName\":\"\",\"PhidTrOcode\":\"0\",\"AppAmtVatFc\":0,\"DescAmtVat\":0,\"RewardsAmtVat\":0,\"AmtSumAll\":0,\"SumPayAmt\":\"\",\"SumAmtDivcnt\":\"\",\"SumPayAmtAll\":\"\",\"SumAmtAllDivcnt\":\"\",\"SumBalAmt\":\"\",\"SumBalBl\":\"\",\"BalAmtAll\":\"\",\"PhidCountAge\":\"0\",\"CountAgeDt\":\"\",\"Remarks\":\"\",\"PhidCntType\":\"169220621000001\",\"PrintCount\":\"\",\"AmtSumAllBb\":73500,\"SumBl\":\"\",\"ThisPayAmt\":0,\"SumYsAmt\":\"\",\"PhidApp\":\"\",\"CurrType\":\"1\",\"ExchRate\":1,\"AppAmtVat\":0,\"AppAmt\":0,\"AppAmtFc\":0,\"AuxName1\":\"\",\"AuxName2\":\"\",\"AuxName3\":\"\",\"PhidDept\":\"0\",\"PhidYsfl\":\"12\",\"RecOrg\":\"0\",\"BRPcNo\":\"\",\"PurchaseMode\":\"\",\"BRCntNo\":\"\",\"Creator\":\"169220606000001\",\"NgInsertDt\":\"\",\"ListFilterVal\":\"\",\"QueryField1Val\":\"\",\"QueryField2Val\":\"\",\"UIMultiConfigID\":\"\",\"AuxItems1\":\"\",\"AuxItems2\":\"\",\"AuxItems3\":\"\",\"PhId\":\"\",\"PhidSchemeId\":\"169220615000047\",\"ImpInfo\":\"\",\"NgRecordVer\":\"\",\"PhidSourcemid\":\"\",\"ItemResource\":\"\",\"WfFlg\":\"\",\"DaFlg\":\"\",\"PhidChkPsn\":\"\",\"ChkDt\":\"\",\"ChkFlg\":\"0\",\"LevelCode\":\"\",\"BillType\":\"7\",\"UserType\":\"\",\"RepAmtFc\":\"\",\"RepAmt\":\"\",\"RepAmtVat\":0,\"RefAmtVatFc\":\"\",\"RefAmtVatEndFc\":\"\",\"ActRelAmt\":\"\",\"ChkSeq\":\"\",\"Freeze\":\"\",\"FreezeCause\":\"\",\"FreezeId\":\"\",\"PhidCntchg\":\"\",\"ImportFlg\":\"\",\"NgUpdateDt\":\"\",\"Editor\":\"\",\"CurOrgId\":\"\",\"TrFlg\":\"0\",\"TrType\":\"\",\"TrNum\":\"\",\"TrDate\":\"\",\"PointId\":\"\",\"PhidTask\":\"\",\"AsrFlg\":\"\",\"key\":\"\"}}}";
    private static final String cntpaydingridData = "{\"PhId\":\"-1\",\"PPhId\":\"\",\"Lineid\":1,\"ItemNo\":\"\",\"ItemName\":\"\",\"PhidBoq\":\"0\",\"PhidBoq_EXName\":\"\",\"PhidBoqD\":\"0\",\"PhidActId\":\"0\",\"PhidActId_EXName\":\"\",\"Spec\":\"\",\"Unit\":\"\",\"Unit_EXName\":\"台\",\"PhidItemId\":\"0\",\"PhidItemId_EXName\":\"\",\"PhidWbs\":\"\",\"PhidWbs_EXName\":\"\",\"PhidCbs\":\"0\",\"PhidCbs_EXName\":\"\",\"PhidProjType\":\"0\",\"PhidProjType_EXName\":\"\",\"Character\":\"\",\"Demand\":\"\",\"PhidCnt\":\"\",\"PhidCntD\":\"\",\"PhidCfori\":\"0\",\"HzCbsWbs\":\"\",\"Prc\":0,\"PrcFc\":0,\"PrcVat\":0,\"PrcVatFc\":0,\"RepQty\":1,\"FzQty\":0,\"CmQty\":1,\"OwnQty\":1,\"AppQty\":1,\"Amt\":0,\"AmtFc\":0,\"AmtVat\":0,\"AmtVatFc\":0,\"CmAmt\":0,\"CmAmtFc\":0,\"CmAmtVat\":0,\"CmAmtVatFc\":0,\"OwnAmt\":0,\"OwnAmtFc\":0,\"OwnAmtVat\":0,\"OwnAmtVatFc\":0,\"AppAmt\":0,\"AppAmtFc\":0,\"AppAmtVat\":0,\"AppAmtVatFc\":0,\"TotalQty\":0,\"TotalPct\":0,\"TaxRate\":0,\"Taxamt\":0,\"KcFreightAmt\":0,\"KcOtherAmt\":0,\"Remarks\":\"\",\"BoqType\":\"\",\"TotalAmt\":0,\"Per\":0,\"SplitFlg\":\"\",\"ItemResource\":\"pcm3_cnt_d\",\"LevelId\":\"0\",\"AddType\":\"1\",\"TimeType\":\"\",\"IsPayChange\":\"\",\"RefAmtVatFc\":0,\"RefAmtVatEndFc\":0,\"PhidFbfw\":\"0\",\"PhidFbfw_EXName\":\"\",\"NgInsertDt\":null,\"NgUpdateDt\":null,\"NgRecordVer\":0,\"Creator\":\"0\",\"Editor\":\"0\",\"CurOrgId\":\"0\",\"PhidSourceMId\":\"\",\"PhidSourceId\":\"\",\"ImpInfo\":\"\",\"RestQty\":0,\"RestAmtVat\":0,\"RestAmtVatFc\":0,\"RestAmt\":0,\"RestAmtFc\":0,\"ControlQty\":0,\"ControlAmtVat\":0,\"ControlAmtVatFc\":0,\"ControlAmt\":0,\"ControlAmtFc\":0,\"AuxItems1\":\"\",\"AuxItems3\":\"\",\"AuxItems2\":\"\",\"PhidItemdata\":\"0\",\"PhidResBs\":\"0\",\"ResPropertys\":\"\",\"CurrType\":\"1\",\"ExchRate\":1,\"PhidPc\":\"0\",\"AuxName1\":\"\",\"AuxName2\":\"\",\"AuxName3\":\"\",\"EnterDt\":null,\"ExitDt\":null,\"UseDays\":0,\"PhidAssetType\":\"0\",\"PhidAssetType_EXName\":\"\",\"AssetProp\":\"\",\"AssetCode\":\"\",\"AssetName\":\"\",\"PhidAsset\":\"0\",\"IsFarmProduce\":0,\"iscf\":\"\",\"CompTotalQty\":0,\"Brand\":\"\",\"TotalSumBb\":0,\"TotalSumUnvatBb\":0,\"RestTotalSumBb\":0,\"RestTotalSumUnvatBb\":0,\"SumTaxrateBb\":0,\"BoqVatFc\":0,\"BoqQty\":0,\"BoqRestQty\":0,\"FyType\":\"0\",\"FySx\":\"0\",\"PhidCntType\":\"\",\"PhidNonmsunit\":\"0\",\"ResMasterData\":\"\",\"CntVatFc\":0,\"CntQty\":1,\"ItemDataNo\":\"\",\"BoqCode\":\"\",\"NonMsunit\":\"\",\"Area\":0,\"UmConvAm\":0,\"Weight\":\"0\",\"Vol\":\"0\",\"CBSAmt\":0,\"CBSBalance\":0,\"CBSQty\":0,\"CBSRestQty\":0,\"CBSCntSumAmt\":0,\"CBSCntTypeBalance\":0,\"IMPSourceTbl\":\"\",\"ThisPer\":1,\"ResOtherName\":\"\",\"ResDescript\":\"\",\"CurrType_Name\":\"人民币\",\"CompTotalAmt\":0,\"CompPer\":0,\"CompThisTotalAmt\":0,\"ThisRk\":0,\"ThisBack\":0,\"ThisActRk\":0,\"RestNeedPayAmt\":1e-12,\"ActPer\":0,\"ResourceName\":\"合同清单信息\",\"PhidPc_EXName\":\"\",\"PhidFeeType\":\"0\",\"PhidFeeType_EXName\":\"\",\"MBillType\":\"7\",\"TotalSum\":0,\"TotalSumUnVat\":0,\"SumTaxrate\":0,\"TaxrateBb\":0,\"TzAmt\":0,\"TzAmtBb\":0,\"TzAmtUntax\":0,\"TzAmtUntaxBb\":0,\"FyVatFc\":0,\"FyVat\":0,\"FyFc\":0,\"Fy\":0,\"FyTaxamt\":0,\"FyTaxamtBb\":0,\"MonPrc\":0,\"MonPrcVatFc\":0,\"MonPrcVat\":0,\"MonPrcFc\":0,\"UseMons\":0,\"MonAmtVatFc\":0,\"MonAmtVat\":0,\"MonAmtFc\":0,\"MonAmt\":0,\"MonTaxamt\":0,\"MonTaxamtBb\":0,\"JzDt\":0,\"shdjsbj\":\"\",\"FyType_EXName\":\"\",\"FySx_EXName\":\"\",\"PhidCntType_EXName\":\"\",\"key\":null,\"user_wlbm\":\"\",\"user_ylcbkm\":\"\"}";



    @Override
    public I8ReturnModel<String> getData(String orgId) {
        List<SettleModel> data = getDataByOrgId(orgId);
        if(!data.isEmpty()){
            data = data.stream().filter(t-> {
                        try {
                            return t.getIsAudit()
                                    && !t.getIsRemoved()
                                    && (t.getServiceType().equals("10") || t.getServiceType().equals("-11"))
                                    && TimeUtils.getDateByDay(t.getOrderDate() + "-01").getTime() >= TimeUtils.getDateByDay("2023-09-01").getTime();
                        } catch (ParseException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    ).collect(Collectors.toList());
        }
        save(orgId, data);
        return I8ReturnModel.success("获取数据成功");
    }

    public I8ReturnModel<String> save(String orgId, List<SettleModel> data) {
        for(SettleModel item : data){
            save(item, orgId);
        }
        return I8ReturnModel.success();
    }

    /**
     * 对应i8采购合同结算
     *
     * @param data
     * @return
     */
    public I8ReturnModel<String> save(SettleModel data, String orgId) {
        try {
            ngLog.info("SettleImpl", "结算单报文->" + JSON.toJSONString(data));

            String PcNo = GetCodeByCode("project_table", "pc_no", "user_mcxmid", orgId);//pcNo
            if (StringUtils.isEmpty(PcNo)) {
                throw new RuntimeException("项目user_mcxmid-{" + orgId + "},不存在！");
            }
            //String pcNo = data.getOrgId().toString();   //项目编码
            String BillDt = data.getOrderDate() + "-01";
            String BillNo = PcNo + data.getOrderCode();
            String cntNo = data.getContractCode();
            String oldPhId = GetPhIdByCode("pcm3_cnt_pay_m", "user_dzbm", BillNo);
            if (StringUtils.isNotEmpty(oldPhId)) {
                throw new RuntimeException("对账单orderCode-{" + BillNo + "},已存在！");
            }

            String PhidCnt = GetPhIdByCode("pcm3_cnt_m", "bill_no", cntNo);
            String PhidPc = GetPhIdByCode("project_table", "user_mcxmid", orgId);//pcNo
            String PhidOCode = GetCodeByCode("project_table", "cat_phid", "phid", PhidPc);
            String Cycle = GetPhIdByFilter("fg3_workcycle", "ctype = 'GCMONTH' and ( '" + BillDt + "' between bdt and edt)");
            String RecCompName = GetPhIdByCode("fg3_enterprise", "compname", data.getSupplierName());
            String title = GetCodeByCode("pcm3_cnt_m", "title", "phid", PhidCnt);

            HashMap<String, Object> main = new HashMap<>();
            main.put("user_dzbm", BillNo);
            main.put("BillNo", BillNo);
            main.put("PhidCnt", PhidCnt);//PhidCnt
            main.put("PhidPc", PhidPc);
            main.put("PhidOCode", PhidOCode);
            main.put("PhidTrOcode", PhidOCode);
            main.put("BillDt", BillDt);
            main.put("PhidCntType", "758220811000003");
            main.put("PhidSchemeId", "758220818000001");
            main.put("Cycle", Cycle);//期间
            main.put("RecCompName", RecCompName);//期间

            main.put("NgInsertDt", TimeUtils.dateToStr(new Date()));
            main.put("AppAmtVatFc", "");//含税金额
            main.put("Remarks", data.getRemark());//备注
            main.put("AmtSumAll", "");//本期结算总额
            main.put("Title", title + "结算-" + BillDt);//备注

            List<SettleDModel> detail = data.getItems();
            ArrayList<HashMap<String, Object>> itemList = new ArrayList<>();

            Integer lineid = 1;
            int phidL = -1;
            for (SettleDModel item : detail) {
                String Unit = GetPhIdByCode("msunit", "msname", item.getMaterialUnit());
                if (StringUtils.isEmpty(Unit)) {
                    Unit = GetPhIdByCode("msunit", "msname", "kg");//pcNo "169220811000001"; //默认kg
                }
                String PhId = Integer.toString(phidL);
                HashMap<String, Object> itemData = new HashMap<>();
                itemData.put("user_wlbm", item.getMaterialCode());
                itemData.put("PhId", PhId);
                itemData.put("key", PhId);
                itemData.put("Lineid", lineid);//行号
                itemData.put("ItemNo", item.getId());
                itemData.put("ItemName", item.getMaterialName());
                itemData.put("PrcFc", item.getTaxFreePrice());
                itemData.put("PrcVatFc", item.getTaxIncludedPrice());
                itemData.put("RepQty", item.getQuantity());
                itemData.put("AppQty", item.getQuantity());
                itemData.put("TaxRate", item.getTaxRate() * 0.01);
                itemData.put("Taxamt", item.getTaxIncludedSum() - item.getTaxFreeSum());
                itemData.put("Remarks", item.getItemRemark());
                itemData.put("PhidCnt", PhidCnt);
                itemData.put("Unit", Unit);
                itemData.put("AmtVatFc", item.getTaxIncludedSum());
                itemData.put("user_ylcbkm", item.getStoreRoomName());
                itemList.add(itemData);
                lineid++;
                phidL--;
            }

            String grid = I8Converter.SetTableRow(cntpaydingridData, itemList);
            String mstformDataStr = I8Converter.SetField(mstformData, main);
            List<NameValuePair> formdata = new ArrayList<>();
            formdata.add(new BasicNameValuePair("mstformData", mstformDataStr));
            formdata.add(new BasicNameValuePair("cntpaydingridData", grid));
            formdata.add(new BasicNameValuePair("cntpaydchggridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydoutgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydrkdgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydingridoldData", grid));
            formdata.add(new BasicNameValuePair("cntpaydchggridoldData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydoutgridoldData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydrkdgridoldData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaydescgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpayfygridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaycaldgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpayrewardsgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntpaysplitgridData", "{ \"table\": { \"key\": \"PhId\" } }"));
            formdata.add(new BasicNameValuePair("cntmodel", "7"));
            formdata.add(new BasicNameValuePair("bustype", "PAY7"));
            formdata.add(new BasicNameValuePair("imptaskid", ""));
            formdata.add(new BasicNameValuePair("attachOutGuid", ""));
            formdata.add(new BasicNameValuePair("isContinue", "false"));
            formdata.add(new BasicNameValuePair("attchmentGuid", "0"));
            formdata.add(new BasicNameValuePair("ng3_logid", "0"));
            I8ReturnModel<String> res = i8Request.PostFormSyncByOcode("/PMS/PCM/CntPayM/save", formdata, "101");
            ngLog.info("SettleImpl", "对账单保存结果：" + res);
            if (res.getIsOk()) {
                return I8ReturnModel.success();
            }
            throw new RuntimeException(res.getMessage());
        } catch (Exception ex) {
            ngLog.error("SettleImpl", "对账单保存异常", ex.getMessage());
            return I8ReturnModel.error(ex.getMessage());
        }
    }

    @Override
    public List<SettleModel> getDataByOrgId(String orgId) {
        //        String orgId = "";//组织机构id
        Integer offset = 0;//从第N条开始
        Integer limit = 100;//
        List<SettleModel> dataList = new ArrayList<>();
        Long version = 0L;//本次请求所要获取的增量数据的version起始值，客户端需要存储接口返回的数据集合中最后一条数据version值
        Long orgIdL = Long.parseLong(orgId);
        while (true) {
            try {
                String apiUrl = String.format(pcrApi, orgIdL, version, limit, offset);
                RequestResult dataBody = client.post(apiUrl, "");
                String content = dataBody.getContent();
                if (StringUtils.isEmpty(content)) {
                    break;
                }
                ComDataModel<SettleModel> res = JSONObject.parseObject(content, new TypeReference<ComDataModel<SettleModel>>(){});
                List<SettleModel> dataArray = res.getData();
                int count = dataArray.size();
                dataList.addAll(dataArray);
                if (count < limit) {
                    break;
                }
                offset = offset + limit;
//                version = dataArray.get(count - 1).getVersion();
            } catch (Exception ex) {
                logger.info(String.format("call api error:  %s", ex.getMessage()), ex);
                break;
            }
        }
        return dataList.stream().distinct().collect(Collectors.toList());
    }
}
